package com.lcx.security.schedule;

import com.lcx.security.FFmpegCommandManager.FFmpegManager;
import com.lcx.security.FFmpegCommandManager.FFmpegManagerImpl;
import com.lcx.security.config.StreamConfig;
import com.lcx.security.dao.TaskDaoImpl;
import com.lcx.security.entity.OutHandler;
import com.lcx.security.entity.TaskEntity;
import com.lcx.security.main.FFmpegCMD;
import com.lcx.security.myenum.StreamEnum;
import com.lcx.security.util.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Component
@EnableScheduling
public class ScheduleTask {

    protected static Logger logger = LoggerFactory.getLogger(StreamConfig.class);

    // 每小时检查前一个小时保存的MP4文件是否正确
    @Scheduled(cron = "0 13 *  ? * *")
    public void checkMP4File(){
        Calendar instance = Calendar.getInstance();
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        hour = hour == 0?23:hour-1;
        String fileName = StreamConfig.FILE_PATH+hour+".mp4";
        String fileNameCopy = StreamConfig.FILE_PATH+instance.get(Calendar.DAY_OF_MONTH)+":"+hour+".mp4";

        File fileCopy = new File(fileNameCopy);
        File file = new File(fileName);
        if (fileCopy.exists() && fileCopy.length() > file.length()-1024*1024*10){
            Path path = Paths.get(fileNameCopy);
            Path toPath = file.toPath();
            try {
                Files.copy(path,toPath, StandardCopyOption.REPLACE_EXISTING);
            } catch (IOException e) {
                logger.error("文件复制异常");
                logger.error(e.getMessage());
            }
        }
    }

    // 清除七天前的MP4
    @Scheduled(cron = "0 0 *  ? * *")
    public void deleteMP4File(){
        Calendar instance = Calendar.getInstance();
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        Date date = new Date(System.currentTimeMillis() - 7 * 24 * 3600 * 1000);
        instance.setTime(date);
        String fileName = StreamConfig.FILE_PATH+instance.get(Calendar.DAY_OF_MONTH)+":"+hour+".mp4";

        File file = new File(fileName);
        if (file.exists()){
            file.delete();
        }
    }

    // 每小时重新启动一个视屏流转换 hls->mp4
    @Scheduled(cron = "0 0 *  ? * *")
    public void hlsToMP4(){
        boolean checkIpPort = IpUtils.checkIpPort(StreamConfig.IP, StreamConfig.PORT);
        FFmpegManager fFmpegManager = new FFmpegManagerImpl();
        if (checkIpPort){
            TaskEntity query = fFmpegManager.query(StreamEnum.RTSP_TO_MP4.getName());
            if (query != null && query.getProcess() != null){
                FFmpegCMD.stopRtspToMp4();
                fFmpegManager.stopAll();
            }
            FFmpegCMD.stopRtspToMp4();
            startRtspToMP4();

        }else{
            fFmpegManager.stopAll();
        }
    }



    private void startRtspToMP4() {
        File file = new File(StreamConfig.FILE_PATH);
        if (!file.exists()){
            file.mkdir();
        }
        Calendar instance = Calendar.getInstance();
        int hour = instance.get(Calendar.HOUR_OF_DAY);
        // String fileName = StreamConfig.FILE_PATH+hour+"_1.mp4";
        String fileName = StreamConfig.FILE_PATH+instance.get(Calendar.DAY_OF_MONTH)+":"+hour+".mp4";
        File mp4 = new File(fileName);
        if (mp4.exists()){
            mp4.delete();
        }
        try {
            FFmpegCMD.rtspToMP4(fileName);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Scheduled(cron = "0 1/5 *  ? * *")
    public void checkHlsToMP4(){
        FFmpegManager fFmpegManager = new FFmpegManagerImpl();
        TaskEntity query = fFmpegManager.query(StreamEnum.HLS_TO_MP4.getName());
        if (query != null && query.getProcess() != null){
            if (checkTaskStatus(query)){
                FFmpegCMD.stopRtspToMp4();
                fFmpegManager.stopAll();
                startRtspToMP4();
            }
        }
    }

    // 判断 TaskEntity 的工作状态 正常工作返回 false
    private boolean checkTaskStatus(TaskEntity taskEntity) {
        if (taskEntity == null || taskEntity.getProcess() == null || !taskEntity.getProcess().isAlive()){
            return true;
        }else {
            OutHandler thread = taskEntity.getThread();
            OutHandler thread1 = taskEntity.getThread1();
            if (thread == null || !thread.getDesstatus() ){
                if (thread1 == null || !thread.getDesstatus()){
                    return true;
                }
            }
            if (!thread.isAlive() && !thread1.isAlive()){
                return true;
            }
        }
        return false;
    }

}
